
global combinar_asm

combinar_asm:
	push rbp
	mov rbp, rsp
	push rbx
	push r12
	push r13
	push r14
	push r15		;armo el stack



; creo máscara alpha
	
	pxor xmm14, xmm14

	movups xmm14, xmm0
	pshufd xmm14, xmm14, 0 		; xmm14 = alpha | alpha | alpha | alpha
	


; creo máscara 255,0

	pxor xmm15, xmm15

	mov eax, 255

	movd xmm15, eax

	pshufd xmm15, xmm15, 0

	cvtdq2ps xmm15, xmm15		; xmm15 = 255,0 | 255,0 | 255,0 | 255,0



	; r8 = ancho de fila en bytes
	; ecx = cantidad de filas

	sub r9, r8			;en r9 me queda el desplazamiento	


	xor rax, rax

	mov rax, r8	
	shr rax, 3
	dec rax
	xor r12, r12
	mov r12, rax	; en  r12 tengo la cantidad de iteraciones por fila

	xor rbx, rbx

	shl rax, 2
	mov rbx, r8		
	sub rbx, rax
	mov r13, rbx	; en  r13 tengo la cantidad de pixels q no entraron en la iteracion por no ser multiplo de 4
	
	xor rax, rax




.ciclo_filas:

	 mov eax, r12d
	.ciclo_columnas:

			; cargo filas y extiendo a 32 bits
			pmovzxbd xmm0, [rdi]			; src_a [0..3]
			pmovzxbd xmm1, [rsi]			; src_b [0..3]

			; convierto a float
			cvtdq2ps xmm0, xmm0
			cvtdq2ps xmm1, xmm1
	
	
			; realizo cálculos

			subps xmm0, xmm1			;src_a - src_b
			
			mulps xmm0, xmm14	; xmm0 = alpha*(a0-b0) | ... | alpha*(a3-b3)
			divps xmm0, xmm15	; xmm0 = alpha*(a0-b0)/255,0 | ... | alpha*(a3-3)/255,0			
			addps xmm0, xmm1 	; xmm0 = alpha*(a0-b0)/255,0 + b0| ... | alpha*(a3-b3)/255,0 + b3

			; convierto a entero
			cvtps2dq xmm0, xmm0
		
			; empaqueto a 16 bits (packed SIGNED dwords -> packed SIGNED words)
			packssdw xmm0, xmm0

			; empaqueto a 8 bits (packed SIGNED words -> packed UNSIGNED words)
			packuswb xmm0, xmm0

			; guardo el resultado
			xor rbx, rbx	
			movd ebx, xmm0
	
			mov [rdx], ebx		 


			; actualizo punteros
			add rsi, 4
			add rdi, 4			
			add rdx, 4				

			; actualizo contador de columnas

			dec eax
			cmp eax, 0

			jz .seguir_viendo
			jmp .ciclo_columnas


.seguir_viendo:
		xor rax, rax
		mov rax, r13
			

		.ciclo2:

			cmp rax, 0
			je .fin_ciclo_columnas

			; cargo filas y extiendo a 32 bits

			pmovzxbq xmm0, [rdi]			; src_a [0..3]
			pmovzxbq xmm1, [rsi]			; src_b [0..3]

			;muevo de a 16 solamente
		
			;ver convierto a float
			cvtdq2ps xmm0, xmm0
			cvtdq2ps xmm1, xmm1
							
			; realizo cálculos
			subps xmm0, xmm1			;src_a - src_b
			mulps xmm0, xmm14	; xmm0 = alpha*(a0-b0) | ... | alpha*(a3-b3)
			divps xmm0, xmm15	; xmm0 = alpha*(a0-b0)/255,0 | ... | alpha*(a3-b3)/255,0		
			addps xmm0, xmm1 	; xmm0 = alpha*(a0-b0)/255,0 + b0| ... | alpha*(a3-b3)/255,0		

			

			; convierto a entero
			cvtps2dq xmm0, xmm0
			
			; empaqueto a 16 bits (packed SIGNED dwords -> packed SIGNED words)
			packssdw xmm0, xmm0

			; empaqueto a 8 bits (packed SIGNED words -> packed UNSIGNED words)
			packuswb xmm0, xmm0

			; guardo el resultado
			xor rbx, rbx	
			movd ebx, xmm0
	
			mov [rdx], ebx		 

			; actualizo punteros

			inc rsi
			inc rdi
			inc rdx			

			; actualizo contador de columnas
			dec rax
			jmp .ciclo2



	.fin_ciclo_columnas:


		add rsi, r9
		add rdi, r9
		add rdx, r9		

		; actualizo contador de filas
		dec rcx

		cmp rcx, 0		
		jz .fin_ciclo_filas

		jmp .ciclo_filas
		

	.fin_ciclo_filas:

		pop r15			;desapilo el stack
		pop r14
		pop r13
		pop r12
		pop rbx
		pop rbp
		ret

